import Taro, {request} from "@tarojs/taro"
import {axios} from 'taro-axios'
import {APP_V, BASE_URL, BD_KEY, P_KEY} from "../constants/api";
import {user} from "./user.service";
import {ServerData} from "./server.interface";
import {GetRequest, getTokenFromCookies} from './tools'

const lxCreateLink = [
  'msvc-order/v2/group/paytoken/',
  'msvc-order/v2/order/paytoken/',
  'msvc-order/v2/order/pay/',
  'msvc-order/v2/group/pay/',
  'msvc-order/v2/order/confirm',
  'msvc-order/v2/cart/pay',
  'msvc-order/v2/order/payinfo',
  'msvc-order/v2/group/create',
  'msvc-order/v2/order/create',
  'api/v3/order/creatRecharge',
  'api/v3/orderPay/getWeixinPayPackageForRecharge',
]

axios.defaults.transformRequest = [function (data) {
  let src = ''
  for (const item in data) {
    src += encodeURIComponent(item) + '=' + encodeURIComponent(data[item]) + '&'
  }
  return src
}]
const requests = axios.create({
  baseURL: BASE_URL,
  timeout: 20000
})
//添加拦截
requests.interceptors.request.use(config => {
  config.headers = newHttp.getHeader({}, config.url ? config.url : '')
  return config
})
requests.interceptors.response.use(res => {
  return res
}, error => {
  console.log(JSON.stringify(error))
  return error.response;
})
const city = Taro.getStorageSync('city');

class NewHttp {
  header = {'Content-Type': 'application/x-www-form-urlencoded'};
  siteHash = ''
  beKey = ''
  mpkey = ''
  areaId = (city && city.region_id) || 0

  getHeader(data: any = {}, url = '') {
    const header = {
      ...this.header,
      ...data,
    };
    const userInfo = Taro.getStorageSync('user')
    const sKey = Taro.getStorageSync('sKey')
    header['apiVersion'] = '3.0'
    header['codeType'] = process.env.TARO_ENV
    if (process.env.TARO_ENV === 'tt') {
      header['from'] = 'bytedance'
      header['codeType'] = 'douyin'
    }
    // 灵锡账号合并APP++header
    if (process.env.TARO_ENV === 'h5' && process.env.P_ENV === 'lx' && url && lxCreateLink.some(item => url && (url.startsWith(BASE_URL + item) || url.indexOf(item) > -1))) {
      header['codeType'] = 'lingxi-app'
    }
    if (sKey) {
      header['s-key'] = sKey;
    }
    const query: any = Taro.getCurrentInstance().router.params;
    if (process.env.TARO_ENV === 'h5') {
      const token = getTokenFromCookies(document.cookie, userInfo)
      header['token'] = token || user.token || userInfo.token || ''
      header['p-key'] = this.getSiteHash()
      header['mp-key'] = this.getMpKey()
    } else {
      header['appVersion'] = APP_V
      header['token'] = user.token || userInfo.token || ''
      header['p-key'] = this.getSiteHash()
    }
    // header['token'] = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJ7XCJ1c2VySWRcIjoxMTY2OTg0fSIsImV4cCI6MTY2OTY5NjAxNiwiaWF0IjoxNjY5NjkyNDE2fQ.cVO84Mp6mV-yBDD6ffi19KPkJerMmESzvme5MXo6xCY'
    if (process.env.TARO_ENV === 'tt') {
      header['bd-key'] = this.getBDKey()
    }
    header['p-key'] = query.pkeys || header['p-key'];
    const pages = Taro.getStorageSync('pages')
    if (pages.length > 0) {
      header['vc_request'] = pages[pages.length - 1]
    }
    if (pages.length > 1) {
      header['vc_referer'] = pages[pages.length - 2]
    }
    const sessionObj = Taro.getStorageSync("sessionObj");
    if (typeof (sessionObj) != "undefined" && null != sessionObj) {
      if (typeof (sessionObj.sessionId) != "undefined" && null != sessionObj.sessionId) {
        header['vc_session'] = sessionObj.sessionId
      }
      if (typeof (sessionObj.step) != "undefined" && null != sessionObj.step) {
        header['vc_step'] = sessionObj.step
      }
    }
    return header;
  }

  getBDKey(){
    if (this.beKey) return this.beKey
    const extConfig = Taro.getExtConfigSync();
    if (JSON.stringify(extConfig['extConfig']) === '{}') {
      this.beKey = BD_KEY
    } else {
      this.beKey = extConfig['extConfig']['bd-key'] || '';
    }
  }

  getSiteHash() {
    if (this.siteHash) return this.siteHash
    if (process.env.TARO_ENV === 'weapp') {
      const extConfig = Taro.getExtConfigSync();
      this.siteHash = extConfig['p-key'] || '';
    } else if (process.env.TARO_ENV === 'tt') {
      const extConfig = Taro.getExtConfigSync();
      if (JSON.stringify(extConfig['extConfig']) === '{}') {
        this.siteHash = P_KEY
      } else {
        this.siteHash = extConfig['extConfig']['p-key'] || '';
      }
    } else {
      const query: any = Taro.getCurrentInstance().router.params;
      const extConfig = Taro.getStorageSync('user');
      this.siteHash = extConfig.pkey || query.pkeys || '';
    }
    return this.siteHash
  }

  getMpKey() {
    if (this.mpkey) {
      if (typeof (this.mpkey) == "undefined" || this.mpkey == 'null') {
        this.mpkey = '';
      }
      return this.mpkey;
    }
    if (process.env.TARO_ENV === 'h5') {
      const extConfig = Taro.getStorageSync('user');
      this.mpkey = extConfig.mpkey;
    }
    if (typeof (this.mpkey) == "undefined" || null == this.mpkey || this.mpkey == 'null') {
      this.mpkey = '';
    }
    return this.mpkey
  }

  async get<T = any>(url: string, param?: { [key: string]: string | number }, isShowToast?): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'get',
        params: param
      })
      return await this.showErrMsg2(ret, isShowToast)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader()
      })
      return await this.showErrMsg2(ret, isShowToast)
    }
  }
  // 灵锡账号合并-新增
  async get_lxMerge<T = any>(url: string, param?: { [key: string]: string | number }, isShowToast?): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'get',
        params: param,
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg2(ret, isShowToast)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg2(ret, isShowToast)
    }
  }

  async catchGet<T = any>(url: string, param?: { [key: string]: string | number }, isShowToast = false, fromWhere? = ""): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'get',
        params: param
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    } else {
      const ret = await Taro.request({
        method: 'GET',
        url: link,
        header: this.getHeader()
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    }
  }

  async catchPost<T = any>(url: string, param?: { [key: string]: string | number }, isShowToast = false, fromWhere? = ""): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'post',
        data: {...param}
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: link,
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    }
  }

  async catchPost_lxMerge<T = any>(url: string, param?: { [key: string]: string | number }, isShowToast = false, fromWhere? = ""): Promise<T | boolean> {
    const link = this.url(url, param);
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'post',
        data: {...param},
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: link,
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg(ret, isShowToast, fromWhere)
    }
  }

  async post<T = any>(url: string, param?: { [key: string]: any }, isShowToast = false): Promise<T | boolean> {
    const location = Taro.getStorageSync('locationData');
    if (location && param) {
      param.lng = location.longitude || '';
      param.lat = location.latitude || '';
    }
    const link = this.url(url, param)
    if (process.env.TARO_ENV === 'h5') {
      const ret = await requests({
        url,
        method: 'post',
        data: {...param}
      })
      return await this.showErrMsg2(ret, isShowToast)
    } else {
      const ret = await Taro.request({
        method: 'POST',
        url: link,
        header: this.getHeader({}, url)
      })
      return await this.showErrMsg2(ret, isShowToast)
    }
  }

  async put<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, showToast = false): Promise<Taro.request.SuccessCallbackResult<T>> {
    const that = this
    url = this.url(url, param)
    return new Promise((resolve, reject) => {
      if (process.env.TARO_ENV === 'h5') {
        request({
          url,
          method: 'put',
          data
        }).then(res => {
          resolve(res)
        }).catch(err => {
          reject(err)
        })
      } else {
        const location = Taro.getStorageSync('locationData');
        if (location) {
          data.lng = location.longitude || '';
          data.lat = location.latitude || '';
        }
        Taro.request({
          method: 'PUT',
          url,
          data,
          header: that.getHeader(),
          success: (res: Taro.request.SuccessCallbackResult<T>) => {
            if (res.statusCode === 400) {
              const msg = res
              if (showToast) {
                Taro.showToast({icon: "none", title: msg.data.message})
              }
              msg['resquest'] = {
                method: 'POST',
                url,
                data,
                header: that.getHeader()
              }
            } else if (res.statusCode == 401) {
              if (process.env.P_ENV === 'lx') {
                if (process.env.TARO_ENV === 'h5') {
                  document.cookie = ''
                }
                Taro.removeStorageSync('user')
              }
              //权限不足，重新登录
              Taro.hideLoading()
              user.jumpLogin()
            }
            resolve(res)
          },
          fail: err => {
            reject(err)
          }
        })
      }
    })
  }

  async put_lxMerge<T = any>(url: string, data: { [key: string]: any }, param?: { [key: string]: string | number }, showToast = false): Promise<Taro.request.SuccessCallbackResult<T>> {
    const that = this
    url = this.url(url, param)
    return new Promise((resolve, reject) => {
      if (process.env.TARO_ENV === 'h5') {
        request({
          url,
          method: 'put',
          data,
          header: this.getHeader({}, url)
        }).then(res => {
          resolve(res)
        }).catch(err => {
          reject(err)
        })
      } else {
        const location = Taro.getStorageSync('locationData');
        if (location) {
          data.lng = location.longitude || '';
          data.lat = location.latitude || '';
        }
        Taro.request({
          method: 'PUT',
          url,
          data,
          header: that.getHeader({}, url),
          success: (res: Taro.request.SuccessCallbackResult<T>) => {
            if (res.statusCode === 400) {
              const msg = res
              if (showToast) {
                Taro.showToast({icon: "none", title: msg.data.message})
              }
              msg['resquest'] = {
                method: 'POST',
                url,
                data,
                header: that.getHeader({}, url),
              }
            } else if (res.statusCode == 401) {
              if (process.env.P_ENV === 'lx') {
                if (process.env.TARO_ENV === 'h5') {
                  document.cookie = ''
                }
                Taro.removeStorageSync('user')
              }
              //权限不足，重新登录
              Taro.hideLoading()
              user.jumpLogin()
            }
            resolve(res)
          },
          fail: err => {
            reject(err)
          }
        })
      }
    })
  }

  async showErrMsg<T = string>(data: request.SuccessCallbackResult<ServerData<T>>, isShowToast = false, fromWhere? = ""): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode == 200) {
        if (isShowToast && fromWhere === "needPage") {
          resolve(data.data);
        } else {
          resolve(data.data.data);
        }
      } else if (statusCode == 204) {
        resolve(statusCode)
      } else if (statusCode == 400) {
        const title = '' + (data.data.message || data.data.msg)
        if (data.data.message !== '未找到订单信息' && data.data.message !== "无供应商身份" && data.data.message !== "创建失败，分销商未启用" && data.data.message !== "创建失败，未查询到分销商信息") {
          Taro.showToast({
            title: title.replace('deep', ''),
            icon: 'none',
          });
        }
        if (isShowToast) {
          resolve(data);
        } else {
          resolve(false)
        }
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else {
        Taro.showToast({
          title: '网络错误：' + statusCode,
          icon: 'none'
        })
        resolve(false)
      }
    })
  }

  async showErrMsg2<T = string>(data: request.SuccessCallbackResult<ServerData<T>>, isShowToast = false): Promise<T | false> {
    return new Promise(async (resolve) => {
      const statusCode = data && (data.statusCode || data.status)
      if (statusCode == 200) {
        resolve(data.data);
      } else if (statusCode == 204) {
        // options 类型请求的正常响应, 不做处理。 不知道会不会影响正常的options请求
      } else if (statusCode == 400) {
        if (isShowToast) {
          resolve(data.data);
        } else {
          const title = '' + (data.data.message || data.data.msg)
          Taro.showToast({
            title: title.replace('deep', ''),
            icon: 'none',
          });
          resolve(false)
        }
      } else if (statusCode == 401) {
        if (process.env.P_ENV === 'lx') {
          if (process.env.TARO_ENV === 'h5') {
            document.cookie = ''
          }
          Taro.removeStorageSync('user')
        }
        Taro.hideLoading()
        user.jumpLogin()
        resolve(false)
      } else if (statusCode == 429) {
        Taro.showToast({
          title: '太多人抢了，请先歇会再点',
          icon: 'none',
        });
        resolve(false)
      } else if (statusCode == 500) {
        Taro.showToast({
          title: '矮油,开小差啦...',
          icon: 'none'
        })
        resolve(false)
      } else {
        Taro.showToast({
          title: '网络错误：' + statusCode,
          icon: 'none'
        })
      }
    })
  }

  url(url: string, param?: { [key: string]: string | number }): string {
    if (/^\/+/.test(url)) {
      url = url.slice(1)
    }
    let service = '';
    if (process.env.TARO_ENV === 'weapp') {
      const extConfig = Taro.getExtConfigSync();
      if (typeof (extConfig['service']) != "undefined" && extConfig['service'] != '' && extConfig['service'] != 'null') {
        service = extConfig['service'] + '/'
      }
    }
    let path;
    if (url.search(/(http|https):\/\//) !== 0) {
      path = BASE_URL + service + url
    } else {
      path = url
    }
    const location = Taro.getStorageSync('locationData');
    if (param) {
      const parameterArr: any[] = [];
      Object.keys(param).map(key => {
        parameterArr.push({
          key,
          val: encodeURIComponent(param[key] !== undefined ? param[key].toString() : ''),
        });
      })
      const parameterStr = parameterArr.map(v => `${v.key}=${v.val}`).join('&');
      if (parameterStr) {
        if (path.indexOf('?') === -1) {
          path += '?' + parameterStr;
        } else {
          path += '&' + parameterStr;
        }
      }
    }
    if (path.indexOf('?') == -1) {
      path += '?lng=' + (location.longitude || '') + '&lat=' + (location.latitude || '');
      path += '&areaId=' + this.areaId;
    } else {
      path += '&lng=' + (location.longitude || '') + '&lat=' + (location.latitude || '');
      path += '&areaId=' + this.areaId;
    }
    return path
  }
}

export const newHttp = new NewHttp();

